#!/bin/bash

# ================================================================
# TooBit监控系统 - 项目启动脚本
# ================================================================
# 作者: AI Assistant
# 创建时间: 2025-08-16
# 版本: v1.0
# 
# 功能说明:
# - 自动检查环境依赖
# - 启动后端Spring Boot服务 (端口: 8080)
# - 启动前端Vue.js服务 (端口: 1024)
# - 提供状态检查和错误诊断
# ================================================================

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目路径配置
PROJECT_ROOT="/Users/austin_w/PycharmProjects/ruoyi-monitor"
BACKEND_PATH="${PROJECT_ROOT}/ChainUp_Monitor_Rear"
FRONTEND_PATH="${PROJECT_ROOT}/ChainUp_Monitor_Front"
JAR_PATH="${BACKEND_PATH}/ruoyi-admin/target/ruoyi-admin.jar"

# 端口配置
BACKEND_PORT=8080
FRONTEND_PORT=1024

# PID文件路径
BACKEND_PID_FILE="${PROJECT_ROOT}/backend.pid"
FRONTEND_PID_FILE="${PROJECT_ROOT}/frontend.pid"

# ================================================================
# 工具函数
# ================================================================

# 打印带颜色的信息
print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_separator() {
    echo "================================================================"
}

# 检查端口是否被占用
check_port() {
    local port=$1
    if lsof -i :$port >/dev/null 2>&1; then
        return 0  # 端口被占用
    else
        return 1  # 端口空闲
    fi
}

# 等待端口启动
wait_for_port() {
    local port=$1
    local timeout=$2
    local count=0
    
    print_info "等待端口 $port 启动中..."
    while [ $count -lt $timeout ]; do
        if check_port $port; then
            print_success "端口 $port 已启动"
            return 0
        fi
        sleep 1
        count=$((count + 1))
        echo -n "."
    done
    echo ""
    print_error "端口 $port 启动超时 (${timeout}秒)"
    return 1
}

# 检查进程是否运行
check_process() {
    local pid=$1
    if ps -p $pid > /dev/null 2>&1; then
        return 0  # 进程存在
    else
        return 1  # 进程不存在
    fi
}

# ================================================================
# 环境检查函数
# ================================================================

check_dependencies() {
    print_separator
    print_info "检查系统依赖..."
    
    # 检查Java
    if command -v java >/dev/null 2>&1; then
        local java_version=$(java -version 2>&1 | head -n 1)
        print_success "Java: $java_version"
    else
        print_error "Java未安装或未配置到PATH"
        exit 1
    fi
    
    # 检查Maven
    if command -v mvn >/dev/null 2>&1; then
        local mvn_version=$(mvn -version 2>/dev/null | head -n 1)
        print_success "Maven: $mvn_version"
    else
        print_warning "Maven未安装 (如需重新编译需要)"
    fi
    
    # 检查Node.js
    if command -v node >/dev/null 2>&1; then
        local node_version=$(node -v)
        print_success "Node.js: $node_version"
    else
        print_error "Node.js未安装或未配置到PATH"
        exit 1
    fi
    
    # 检查NPM
    if command -v npm >/dev/null 2>&1; then
        local npm_version=$(npm -v)
        print_success "NPM: $npm_version"
    else
        print_error "NPM未安装或未配置到PATH"
        exit 1
    fi
}

check_project_files() {
    print_separator
    print_info "检查项目文件..."
    
    # 检查项目根目录
    if [ ! -d "$PROJECT_ROOT" ]; then
        print_error "项目根目录不存在: $PROJECT_ROOT"
        exit 1
    fi
    print_success "项目根目录: $PROJECT_ROOT"
    
    # 检查后端JAR文件
    if [ ! -f "$JAR_PATH" ]; then
        print_error "后端JAR文件不存在: $JAR_PATH"
        print_info "请先运行以下命令编译后端:"
        echo "  cd $BACKEND_PATH"
        echo "  mvn clean package -DskipTests"
        exit 1
    fi
    print_success "后端JAR文件: $JAR_PATH"
    
    # 检查前端目录和依赖
    if [ ! -d "$FRONTEND_PATH" ]; then
        print_error "前端目录不存在: $FRONTEND_PATH"
        exit 1
    fi
    print_success "前端目录: $FRONTEND_PATH"
    
    if [ ! -d "$FRONTEND_PATH/node_modules" ]; then
        print_error "前端依赖未安装"
        print_info "请先运行以下命令安装前端依赖:"
        echo "  cd $FRONTEND_PATH"
        echo "  npm install"
        exit 1
    fi
    print_success "前端依赖已安装"
}

check_database() {
    print_separator
    print_info "检查数据库连接..."
    
    # 简单检查MySQL进程
    if pgrep -x "mysqld" >/dev/null; then
        print_success "MySQL服务正在运行"
    elif brew services list 2>/dev/null | grep mysql | grep started >/dev/null; then
        print_success "MySQL服务正在运行 (Homebrew)"
    else
        print_warning "未检测到MySQL服务"
        print_info "请确保MySQL服务已启动:"
        echo "  # macOS (Homebrew):"
        echo "  brew services start mysql"
        echo "  # Linux:"
        echo "  sudo systemctl start mysql"
        echo ""
        read -p "是否继续启动项目? (y/N): " -n 1 -r
        echo ""
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
}

# ================================================================
# 服务启动函数
# ================================================================

start_backend() {
    print_separator
    print_info "启动后端服务..."
    
    # 检查端口是否被占用
    if check_port $BACKEND_PORT; then
        print_warning "后端端口 $BACKEND_PORT 已被占用"
        print_info "尝试查看占用进程:"
        lsof -i :$BACKEND_PORT
        read -p "是否强制停止占用进程并继续? (y/N): " -n 1 -r
        echo ""
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            local pid=$(lsof -ti :$BACKEND_PORT)
            if [ ! -z "$pid" ]; then
                kill -9 $pid
                print_success "已停止占用进程: $pid"
                sleep 2
            fi
        else
            exit 1
        fi
    fi
    
    # 启动后端服务
    cd "$(dirname $JAR_PATH)"
    print_info "在目录 $(pwd) 启动后端服务..."
    
    # 使用nohup在后台启动
    nohup java -jar \
        -Xms256m \
        -Xmx1024m \
        -XX:MetaspaceSize=128m \
        -XX:MaxMetaspaceSize=512m \
        "$(basename $JAR_PATH)" \
        > ../../../backend.log 2>&1 &
    
    local backend_pid=$!
    echo $backend_pid > "$BACKEND_PID_FILE"
    
    print_info "后端服务PID: $backend_pid"
    print_info "日志文件: ${PROJECT_ROOT}/backend.log"
    
    # 等待后端启动
    if wait_for_port $BACKEND_PORT 30; then
        print_success "后端服务启动成功! 端口: $BACKEND_PORT"
        
        # 测试后端响应
        sleep 2
        if curl -s -o /dev/null -w "%{http_code}" http://localhost:$BACKEND_PORT | grep -q "200\|302"; then
            print_success "后端服务响应正常"
        else
            print_warning "后端服务可能还在启动中..."
        fi
    else
        print_error "后端服务启动失败"
        print_info "请检查日志: ${PROJECT_ROOT}/backend.log"
        tail -20 "${PROJECT_ROOT}/backend.log"
        exit 1
    fi
}

start_frontend() {
    print_separator
    print_info "启动前端服务..."
    
    # 检查端口是否被占用
    if check_port $FRONTEND_PORT; then
        print_warning "前端端口 $FRONTEND_PORT 已被占用"
        print_info "尝试查看占用进程:"
        lsof -i :$FRONTEND_PORT
        read -p "是否强制停止占用进程并继续? (y/N): " -n 1 -r
        echo ""
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            local pid=$(lsof -ti :$FRONTEND_PORT)
            if [ ! -z "$pid" ]; then
                kill -9 $pid
                print_success "已停止占用进程: $pid"
                sleep 2
            fi
        else
            exit 1
        fi
    fi
    
    # 启动前端服务
    cd "$FRONTEND_PATH"
    print_info "在目录 $(pwd) 启动前端服务..."
    
    # 使用nohup在后台启动
    nohup npm run dev > ../frontend.log 2>&1 &
    local frontend_pid=$!
    echo $frontend_pid > "$FRONTEND_PID_FILE"
    
    print_info "前端服务PID: $frontend_pid"
    print_info "日志文件: ${PROJECT_ROOT}/frontend.log"
    
    # 等待前端启动
    if wait_for_port $FRONTEND_PORT 20; then
        print_success "前端服务启动成功! 端口: $FRONTEND_PORT"
    else
        print_error "前端服务启动失败"
        print_info "请检查日志: ${PROJECT_ROOT}/frontend.log"
        tail -20 "${PROJECT_ROOT}/frontend.log"
        exit 1
    fi
}

# ================================================================
# 状态检查函数
# ================================================================

show_status() {
    print_separator
    print_info "服务状态检查..."
    
    # 检查后端
    if [ -f "$BACKEND_PID_FILE" ]; then
        local backend_pid=$(cat "$BACKEND_PID_FILE")
        if check_process $backend_pid && check_port $BACKEND_PORT; then
            print_success "后端服务运行正常 (PID: $backend_pid, 端口: $BACKEND_PORT)"
        else
            print_error "后端服务异常"
        fi
    else
        print_error "后端服务未启动"
    fi
    
    # 检查前端
    if [ -f "$FRONTEND_PID_FILE" ]; then
        local frontend_pid=$(cat "$FRONTEND_PID_FILE")
        if check_process $frontend_pid && check_port $FRONTEND_PORT; then
            print_success "前端服务运行正常 (PID: $frontend_pid, 端口: $FRONTEND_PORT)"
        else
            print_error "前端服务异常"
        fi
    else
        print_error "前端服务未启动"
    fi
    
    print_separator
    print_info "访问地址:"
    echo "  🌐 前端管理界面: http://localhost:$FRONTEND_PORT"
    echo "  🔧 后端API服务:  http://localhost:$BACKEND_PORT"
    echo "  📱 网络访问:     http://$(hostname -I | awk '{print $1}'):$FRONTEND_PORT"
}

# ================================================================
# 主函数
# ================================================================

main() {
    print_separator
    echo -e "${BLUE}🚀 TooBit监控系统启动脚本${NC}"
    print_separator
    
    # 环境检查
    check_dependencies
    check_project_files
    check_database
    
    # 启动服务
    start_backend
    start_frontend
    
    # 显示状态
    show_status
    
    print_separator
    print_success "项目启动完成!"
    print_info "您可以运行以下命令:"
    echo "  📊 查看状态: $0 status"
    echo "  🛑 停止服务: $0 stop"
    echo "  📝 查看日志: tail -f ${PROJECT_ROOT}/backend.log"
    echo "  📝 查看日志: tail -f ${PROJECT_ROOT}/frontend.log"
    print_separator
}

# ================================================================
# 停止服务函数
# ================================================================

stop_services() {
    print_separator
    print_info "停止所有服务..."
    
    # 停止后端
    if [ -f "$BACKEND_PID_FILE" ]; then
        local backend_pid=$(cat "$BACKEND_PID_FILE")
        if check_process $backend_pid; then
            kill $backend_pid
            print_success "已停止后端服务 (PID: $backend_pid)"
        fi
        rm -f "$BACKEND_PID_FILE"
    fi
    
    # 停止前端
    if [ -f "$FRONTEND_PID_FILE" ]; then
        local frontend_pid=$(cat "$FRONTEND_PID_FILE")
        if check_process $frontend_pid; then
            kill $frontend_pid
            print_success "已停止前端服务 (PID: $frontend_pid)"
        fi
        rm -f "$FRONTEND_PID_FILE"
    fi
    
    # 额外清理
    sleep 2
    pkill -f "ruoyi-admin.jar" 2>/dev/null || true
    pkill -f "vue-cli-service serve" 2>/dev/null || true
    
    print_success "服务停止完成!"
}

# ================================================================
# 脚本入口
# ================================================================

case "${1:-start}" in
    "start")
        main
        ;;
    "stop")
        stop_services
        ;;
    "restart")
        stop_services
        sleep 3
        main
        ;;
    "status")
        show_status
        ;;
    "help"|"-h"|"--help")
        echo "用法: $0 [命令]"
        echo ""
        echo "命令:"
        echo "  start    启动项目 (默认)"
        echo "  stop     停止项目"
        echo "  restart  重启项目"
        echo "  status   查看状态"
        echo "  help     显示帮助"
        echo ""
        echo "注意事项:"
        echo "  - 请确保MySQL数据库已启动"
        echo "  - 确保端口 8080 和 1024 未被占用"
        echo "  - 首次运行前请确保已编译后端和安装前端依赖"
        ;;
    *)
        print_error "未知命令: $1"
        echo "运行 '$0 help' 查看帮助"
        exit 1
        ;;
esac
